<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <script src="js/vue.js"></script>
    <style>
        .box {
            border: 1px solid #cccccc;
        }
    </style>
    <script>
        // 1、方法定义
        function show(a){

        }
        // 2、方法调用
        show(123);
        // 下属方法时可以定义自定义事件的
        // new CustomEvent()
    </script>
</head>

<body>
    <div id="app">
        <h3>父组件</h3>
        <input type="button" value="打印子组件实例" @click="printChild()">
        <p>msg:{{ msg }}</p>
        <p>num:{{ num }}</p>

        <!-- <comp-a @click.native="loadNum()"></comp-a> -->
        <comp-a @send-num="loadNum"></comp-a>

    </div>
    <template id="compa">
        <div class="box">
            <h3>子组件</h3>
            <p>msg:{{ msg }}</p>
            <input type="button" value="将MSG发生到父组件" @click="sendMsg()">
            <p>num:{{ num }}</p>
            <input type="button" value="将NUM发生到父组件" @click="sendNum()">
        </div>
    </template>
</body>
<script>
    Vue.component("CompA", {
        template: "#compa",
        data(){
            return {
                msg:"子组件A的数据",
                num:123
            }
        },
        methods: {
            sendMsg(){
                this.$parent.loadMsg(this.msg);
            },
            sendNum(){
                console.log("sendNum");
                this.$emit("send-num",this.num,this.msg);
            }
        },
        mounted() {
            console.log(this);
        },
    })
    /*
        1、借助方法的实参到形参的传递实现数据共享
            + 在子组件通过vm.$parent调用父组件的方法，并且携带参数
            + 在父组件中定义相关的方法，并接受形参，将形参赋值到父组件变量中
        2、事件绑定+事件触发
            基于的原理时JS中方法定义时和方法调用时，实参和形参的对应关系
            + 事件绑定：采用Vue事件绑定语法，v-on 在子组件标签上绑定自定义事件
                => 组件上的事件默认会被子组件进行事件拦截处理，并存储于特殊仓库_events仓库
                    -> 被绑定的事件名称会统一转换为小写，但不会处理特殊定义方式
                    -> 用于数据传递的事件，绑定时方法不能定义 ()
                => 如果事件绑定时，使用了修饰符 .native ,此时该事件会传递到子组件跟标签进绑定监听
                    -> 因为可以通过 .native 修饰符将事件绑定在子组件根标签上
                    -> 因此在定义子组件向父组件传递数据的事件时，不要使用已知的事件名称
            + 事件触发：Vue中提个一个特殊的实例方法 vm.$emit(),该方法用于执行当前组件_events中的相关事件
                => vm.$emit(eventName,...arg) eventName描述需要触发的事件名称
                                              ...arg 不定义长参数，该方法后可以接受不定选项的实参
                                              定义的参数会直接作为 eventName 绑定的方法参数 按照顺序进行传递
    */
    new Vue({
        el: '#app',
        data:{
            msg:"",
            num:0
        },
        methods: {
            printChild(){
                // vm.$children 该实例属性是用于获取当前组件的所有子组件实例
                //      1、将子组件存储为一个数组，但数组中的组件顺序不定
                //      2、不具有响应式功能
                console.log(this.$children);
            },
            loadMsg(arg){
                console.log(arg);
                this.msg = arg;
            },
            loadNum(a,b){
                console.log("loadNum方法:",a,b);
                this.num = a;
            }
        },
    });
</script>

</html>